package com.zbkj.service.monitor.channel.hemengyun.request;

import cn.hutool.core.lang.Console;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.HMac;
import cn.hutool.crypto.digest.HmacAlgorithm;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.zbkj.common.exception.AppException;
import com.zbkj.common.monitorchannel.vo.hemengyun.HeMengYunResultV3Vo;
import com.zbkj.common.monitorchannel.vo.hemengyun.HeMengYunResultVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @ClassName: HeMengYunHelper 3.0
 * @Description: 鹤梦云PaaS能力平台
 * @Author: fanbing
 * @Version: V1.0
 **/
@Component
@Slf4j
public class HeMengYun3Helper {


    @Value("${hemengyun.accesskey:G021l7egdug5w4tx}")
    private String accessKey;

    @Value("${hemengyun.accesssecret}")
    private String accessSecret = "";

    private String ENC = "UTF-8";


    public <T> T post(String url, String path, String Authorization, String data, TypeReference<T> typeReference) {
        log.info("鹤梦云PaaS能力平台V3版本请求Data:{};url:{}", data, url);
        String Data = aesEncrypt(data);
        String Timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String Nonce = UUID.randomUUID().toString();

        String Ver = "3.0";

        Map<String, String> m = new HashMap<>();
        m.put("AccessKey", accessKey);
        m.put("Timestamp", Timestamp);
        m.put("Nonce", Nonce);
        m.put("Data", Data);
        m.put("Path", path);
        String Signature = sign(m);
        m.put("Signature", Signature);
        m.put("Ver", Ver);


        String rsp = HttpUtil.createPost(url + path)//
                .header("Authorization", Authorization)
                .header("Ver", Ver)//
                .body(JSON.toJSONString(m), "text/plain")//
                .execute().body();

        log.info("鹤梦云PaaS能力平台响V3应数据Data:{};rsp:{};path={}", data, rsp, path);


        try {
            HeMengYunResultV3Vo resultV3Vo = JSON.parseObject(rsp, new TypeReference<HeMengYunResultV3Vo>() {
            });

            String json = aesDecrypt(resultV3Vo.getData());

            T t = JSON.parseObject(json, typeReference);

            return t;

        } catch (Exception e) {
            throw new AppException("鹤梦云PaaS能力平台V3版本响应数据转换json失败：" + rsp);
        }

    }

    /**
     * 加密
     *
     * @param data
     * @return
     */
    private String aesEncrypt(String data) {
        try {

            AES aes = new AES("CBC", "PKCS5Padding", accessKey.getBytes(ENC), accessSecret.getBytes(ENC));
            String eh = aes.encryptBase64(data);

            return eh;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 解密
     *
     * @param data
     * @return
     */
    public String aesDecrypt(String data) {
        try {

            AES aes = new AES("CBC", "PKCS5Padding", accessKey.getBytes(ENC), accessSecret.getBytes(ENC));
            String eh = aes.decryptStr(data);

            return eh;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


    private String sign(Map<String, String> m) {

        Map<String, String> map = sortMapByKey(m);
        StringBuffer sb = new StringBuffer();

        map.forEach((key, val) -> {
            if (StrUtil.trim(val).length() > 0) {
                sb.append(key).append(val);
            }
        });

        try {

            HMac mac = new HMac(HmacAlgorithm.HmacSHA256, accessSecret.getBytes(ENC));

            String macHex1 = mac.digestHex(sb.toString());
            return macHex1;
        } catch (Exception e) {
            Console.log(e.getMessage(), e);
        }
        return null;

    }


    private static Map<String, String> sortMapByKey(Map<String, String> map) {

        if (map == null || map.isEmpty()) {
            return null;
        }

        Map<String, String> sortMap = new TreeMap<String, String>((str1, str2) -> str1.compareTo(str2));
        sortMap.putAll(map);
        return sortMap;

    }
}
